<?php

namespace App\Http\Controllers\V1\Api;

use App\Helper\AliyunSDK;
use App\Helper\UmengSDK;

use App\Http\Requests\Api\UsersServer;
use App\Models\V1\Config;
use App\Models\V1\DeveloperOperationLog;
use App\Models\V1\Preparatory;
use App\Models\V1\Users;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Ramsey\Uuid\Uuid;
use Exception;
use App\Models\V1\SmsCodeRecord;


class AuthController extends BaseController
{
    /**
     * 用户登录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {

        //par 1账户 2手机
        $par = $request->input('par', 2);
        $agree = $request->input('agree', '');
        $mobile = $request->input('mobile', "");
        $code = $request->input('code', "");
        $username = $request->input('username', "");
        if ($par == 1) {
            if (empty($agree)) {
                return ajax_output(300, "必须同意用户条款");
            }
            $credentials = $request->only(['username', 'password']);
            if (!$token = auth('box')->attempt($credentials)) {
                return ajax_output(300, "用户名或密码错误");
            }
            $user_model = new Users();
            $user = $user_model->where("username", $username)->where('state', 1)->first();

            if (!$user) {
                return ajax_output(300, "没有这个用户或被禁用");
            }
            // 添加开发者操作日志
            DeveloperOperationLog::query()->create([
                'user' => $user['id'],
                'ip' => $request->getClientIp(),
                'ulid' => time(),
                'attributes' => !empty($request->all()) ? json_encode($request->all()) : null,
                'remark' => '用户登录',
            ]);

            return ajax_output(200, "成功", ['token' => $token, 'id' => $user['id'], 'audit_status' => $user['audit_status'], 'state' => $user['state'], 'pid' => $user['pid']]);
        } else {

            if (empty($agree)) {
                return ajax_output(300, "必须同意用户条款");
            }
            if (empty($mobile)) {
                return ajax_output(300, "请传手机号");
            }
            if (empty($code)) {
                return ajax_output(300, "请传验证码");
            }

            // 校验验证码
            $this->VerifyCode($mobile, $code, 'login');

            $user_model = new Users();
            $user = $user_model->where("mobile", $mobile)->where('state', 1)->first();

            if (!$user) {
                return ajax_output(300, "没有这个用户或被禁用");
            }

            // 添加开发者操作日志
            DeveloperOperationLog::query()->create([
                'user' => $user['id'],
                'ip' => $request->getClientIp(),
                'ulid' => time(),
                'attributes' => !empty($request->all()) ? json_encode($request->all()) : null,
                'remark' => '用户登录',
            ]);

            $token = auth('box')->login($user);
            return ajax_output(200, "成功", ['token' => $token, 'id' => $user['id'], 'mobile' => $user['mobile'], 'state' => $user['state'], 'integral' => $user['integral']]);

        }


    }


    /**
     * 忘记密码 步骤一
     * @param Request $request
     * @return void
     */
    public function forgot_step1(Request $request)
    {
        $username = $request->input('username', "");
        $user_model = new Users();
        $user = $user_model->where("username", $username)->first();
        if (!$user) {
            return ajax_output(300, "账号不存在");
        }
        if (empty($user->mobile)) {
            return ajax_output(300, "未绑定有效手机号码，联系客服找回");
        }
        return ajax_output(200, "成功", $user->mobile);
    }

    /**
     * 忘记密码 步骤二
     * @param Request $request
     * @return void
     */
    public function forgot_step2(Request $request)
    {
        $username = $request->input('username', "");
        $client_id = $request->input('client_id', "");
        $code = $request->input('code', "");
        if (empty($username) || empty($code)) {
            return ajax_output(300, "参数错误");
        }
        $user_model = new Users();
        $user = $user_model->where("username", $username)->first();
        if (empty($user->mobile)) {
            return ajax_output(300, "手机号码不全，请跟换其他方式找回");
        }
        $aliyun_sdk = new AliyunSDK();
        if (!$aliyun_sdk->verify_sms($user->mobile, $code, $client_id)) {
            return ajax_output(300, "短信验证码错误");
        }
        //重置用户的token值，用于三阶段校验
        $user->update([
            'token' => Uuid::uuid1(time())->toString()
        ]);
        return ajax_output(200, "成功", ['token' => $user->token]);
    }

    /**
     * 忘记密码 步骤三
     * @param Request $request
     * @return void
     */
    public function forgot_step3(Request $request)
    {
        $username = $request->input('username', "");
        $pasword = $request->input('password', "");
        $confirm_password = $request->input('confirm_password', "");
        $token = $request->input('token', "");
        if (empty($username) || empty($pasword) || empty($confirm_password) || empty($token)) {
            return ajax_output(300, "参数错误");
        }
        if ($pasword != $confirm_password) {
            return ajax_output(300, "两次密码不一致");
        }

        $user_model = new Users();
        $user = $user_model->where("username", $username)->first();
        if ($user->token != $token) {
            return ajax_output(300, "非法操作");
        }
        //更新密码
        $user->update([
            'password' => bcrypt($pasword)
        ]);
        return ajax_output(200, "成功");
    }

    /**
     * 退出登录
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        if (auth('box')->user()) {
            auth('box')->logout();
        }
        return ajax_output(200, "成功");
    }


    /**
     * 找回密码
     * @param Request $request
     * @return void
     */
    public function retpas(Request $request)
    {

        $mobile = $request->input('mobile', "");
        $password = $request->input('password', "");
        $affirm_password = $request->input('affirm_password', "");
        $code = $request->input('code', "");

        if (empty($mobile) || empty($code) || empty($password) || empty($affirm_password)) {
            return ajax_output(300, "参数错误");
        }
        if ($password != $affirm_password) {
            return ajax_output(300, "两次密码不一样");
        }
        // 校验验证码
        $this->VerifyCode($mobile, $code, 'retrieve_password');

        $user_model = new Users();
        $user = $user_model->where("mobile", $mobile)->first();

        if (!$user) {
            return ajax_output(300, "账号不存在");
        }


        $res = $user_model->where('mobile', $mobile)->update([
            'password' => bcrypt($password),
        ]);

        if (!$res) {
            return ajax_output(300, "找回失败");
        } else {
            return ajax_output(200, "成功", $user->mobile);
        }


    }


    /**
     * 注册用户
     * @param UsersServer $request
     * @return void
     */
    public function register(UsersServer $request)
    {
        $request->validate('v1.create');
        $agree = $request->input('agree', '');
        $mobile = $request->input('mobile', "");
        $community_id = $request->input('community_id', "");
        $partition = $request->input('partition', "");
        $building = $request->input('building', "");
        $hnum = $request->input('hnum', "");
        $floor = $request->input('floor', "");
        $code = $request->input('code', "");
        if (empty($agree)) {
            return ajax_output(300, "必须同意用户条款");
        }


        // 校验验证码
        $this->VerifyCode($mobile, $code, 'register');
        $user_model = new Users();
        //查询用户名或手机号码是否存在
        $user = $user_model->where('mobile', $mobile)->first();
        if ($user) {
            return ajax_output(300, "手机号码已经存在");
        }
        $integral = Config::where('id', 1)->value('config_value');//注册送米米
        $preparatory_id = Preparatory::where('community_id', $community_id)->value('id');


        $user_model->create([
            'mobile' => $mobile,
            'username' => $mobile,
            'community_id' => $community_id,
            'preparatory_id' => $preparatory_id,
            'partition' => $partition,
            'building' => $building,
            'hnum' => $hnum,
            'floor' => $floor,
            'integral' => $integral,

        ]);
        return ajax_output(200, "注册成功");
    }


    /**
     * 发送短信
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendSms(Request $request)
    {
        $mobile = $request->input('mobile', '');
        $scene = $request->input('scene', '');
        if (empty($mobile)) {
            return ajax_output(300, "必须传手机号");
        }
        if (empty($scene)) {
            return ajax_output(300, "必须传场景");
        }
        if (!isMobile($mobile)) {
            return ajax_output(300, "手机号格式不正确");
        }

        // 发送间隔验证(1分钟只能发送一次)
        $verifyTime = date('Y-m-d H:i:s', strtotime('-1 Minute', time()));
        $sendCount = SmsCodeRecord::query()->where('mobile', $request['mobile'])
            ->where('created_at', '>=', $verifyTime)->count();
        if ($sendCount >= 1) {
            throw new Exception('单个手机号一分钟只能发送一次', 500);

        }
        $aliyunSdk = new AliyunSDK();


        $result = $aliyunSdk->sendSms($mobile, $scene);
        if ($result['state']) {
            return ajax_output(200, "发送成功",666666);
        } else {
            return ajax_output(300, "发送失败");
        }

    }


    /**
     * 验证码验证
     *
     * @param string $mobile
     * @param string $code
     * @param string $scene
     * @return true
     * @throws Exception
     */
    public function VerifyCode(string $mobile, string $code, string $scene): bool
    {

        $sql = SmsCodeRecord::query()->where([
            ['mobile', $mobile],
            ['scene', $scene],
            ['code', $code],
        ]);
        $isExists = (clone $sql)->exists();

        if (!$isExists) {
            throw new Exception('请先获取验证码', 500);
        }

        $logInfo = (clone $sql)->first()->toArray();

        // 使用状态验证
        if ($logInfo['state']) {
            throw new Exception('验证码已使用', 500);
        }

        // 超时验证 (5分钟超时)
        $validTime = max(1, 5);
        if ((time() - strtotime($logInfo['created_at'])) >= ($validTime * 60)) {
            throw new Exception('验证码已过期', 500);
        }

        try {
            // 将本次验证码状态改为已使用
            (clone $sql)->update([
                'state' => 1,
            ]);

            return true;
        } catch (Exception $ex) {
            throw new Exception('请重新获取验证码', 500);
        }

    }


}
